/**
 *
 */
package com.naiterui.ehp.bs.recommend.remote;

import com.google.common.collect.Lists;
import com.naiterui.common.repository.page.PageParamVO;
import com.naiterui.common.repository.page.PageVO;
import com.naiterui.ehp.bp.bo.b2c.ProductBoxBO;
import com.naiterui.ehp.bp.bo.b2c.ProductInventoryBO;
import com.naiterui.ehp.bp.bo.cms.DrRecordAuthorityBO;
import com.naiterui.ehp.bp.bo.doctor.RecomUserInfoBO;
import com.naiterui.ehp.bp.bo.emr.DrRecordIdBO;
import com.naiterui.ehp.bp.bo.emr.MedicalRecordBO;
import com.naiterui.ehp.bp.bo.emr.MedicalRecordDoctorBO;
import com.naiterui.ehp.bp.bo.emr.params.DrCaseParams;
import com.naiterui.ehp.bp.bo.im.RecomSendDTO;
import com.naiterui.ehp.bp.bo.medication.MedicationDefaultUsageBO;
import com.naiterui.ehp.bp.bo.medication.MedicationDetailBO;
import com.naiterui.ehp.bp.bo.medication.param.MedicationParamBO;
import com.naiterui.ehp.bp.bo.recommend.param.RecomBuyNotifyParamBO;
import com.naiterui.ehp.bp.constants.CommonConstant;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bp.support.exception.ResponseVO;
import com.naiterui.ehp.bp.support.utils.JsonMapper;
import com.naiterui.ehp.bp.utils.date.DateUtil;
import com.naiterui.ehp.bp.utils.lang.StringUtil;
import com.naiterui.ehp.bp.utils.net.RestHttpUtil;
import com.naiterui.ehp.bs.recommend.vo.InventoryInfoVo;
import com.naiterui.ehp.bs.recommend.vo.MedicationBoxVO;
import com.naiterui.ehp.bs.recommend.vo.PatientNameVO;
import com.naiterui.ehp.bs.recommend.vo.SkuVO;
import com.naiterui.ehp.bs.recommend.vo.dto.DoctorRecordDTO;
import com.naiterui.ehp.bs.recommend.vo.dto.IMRecomRemindDTO;
import com.naiterui.ehp.bs.recommend.vo.dto.IMSendResultDTO;
import com.naiterui.ehp.bs.recommend.vo.dto.RecordHospitalDTO;
import com.naiterui.ehp.bs.recommend.vo.param.DiagnosisVO;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.stereotype.Service;

/**
 * @author guoyongxiang
 * @since 2.9.0
 */
@Service
@AllArgsConstructor
public class RecommendRemoter implements IRecommendRemoter {

    private static Logger LOGGER = LoggerFactory.getLogger(RecommendRemoter.class);

    private final RecommendRemoterConfig recommendRemoterConfig;

    @Override
    public boolean checkDrToken(String doctorId, String token) throws BusinessException {
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("doctorId", doctorId);
        paramMap.put("token", token);
        return RestHttpUtil.post()
                           .url(this.recommendRemoterConfig.getCheckDrTokenUrl())
                           .paramMap(paramMap)
                           .executeData(new ParameterizedTypeReference<ResponseVO<Boolean>>() {
                           });

    }

    @Override
    public Boolean saveRemarkName(Long doctorId, Long patientId, String patientName, Integer gender, Integer age, String ageUnit)
            throws BusinessException {
        Map<String, String> params = new HashMap<>();
        if (doctorId != null) {
            params.put("doctorId", String.valueOf(doctorId));
        }
        if (patientId != null) {
            params.put("patientId", String.valueOf(patientId));
        }
        params.put("patientName", patientName);
        params.put("gender", gender + "");
        params.put("age", age + "");
        params.put("ageUnit", ageUnit);
        return RestHttpUtil.post()
                           .url(this.recommendRemoterConfig.getSaveRemarknameUrl())
                           .paramMap(params)
                           .executeData(new ParameterizedTypeReference<ResponseVO<Boolean>>() {
                           });
    }

    @Override
    public RecomUserInfoBO getUserInfo(Long doctorId, Long patientId, boolean... fetchNickname) throws BusinessException {
        Map<String, String> paramMap = new HashMap<>();
        if (doctorId != null) {
            paramMap.put("doctorId", doctorId + "");
        }
        if (patientId != null) {
            paramMap.put("patientId", patientId + "");
        }
        // 默认获取昵称
        boolean fetchBool = true;
        if (fetchNickname.length > 0) {
            fetchBool = fetchNickname[0];
        }
        Integer fetchStatus = fetchBool ? CommonConstant.FETCH_PT_NICKNAME_TRUE : CommonConstant.FETCH_PT_NICKNAME_FALSE;
        // 是否获取昵称
        paramMap.put("fetchNickname", String.valueOf(fetchStatus));

        return RestHttpUtil.post()
                           .url(this.recommendRemoterConfig.getRecomUserInfoUrl())
                           .paramMap(paramMap)
                           .executeData(new ParameterizedTypeReference<ResponseVO<RecomUserInfoBO>>() {
                           });
    }

    @Override
    public IMSendResultDTO sendRecomMessage(RecomSendDTO recomSendDTO) throws BusinessException {
        return RestHttpUtil.post()
                           .url(this.recommendRemoterConfig.getImSendRecomUrl())
                           .body(JsonMapper.toJson(recomSendDTO))
                           .executeData(new ParameterizedTypeReference<ResponseVO<IMSendResultDTO>>() {
                           });
    }

    @Override
    public void updateConsultSessionRecomFlag(Long consultSessionId) throws BusinessException {
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("consultSessionId", consultSessionId + "");
        RestHttpUtil.post()
                    .url(this.recommendRemoterConfig.getDrUpdateSessionRecomFlag())
                    .paramMap(paramMap)
                    .executeData();
    }

    @Override
    public void rePurchaseRemindReset(Long patientId) throws BusinessException {
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("patientId", patientId + "");
        RestHttpUtil.post()
                    .url(this.recommendRemoterConfig.getDrRePurchaseRemindReset())
                    .paramMap(paramMap)
                    .executeData();
    }

    @Override
    public DoctorRecordDTO getDoctorRecordByDoctorId(Long doctorId) throws BusinessException {
        String doctorIdStr = doctorId.toString();
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("doctorId", doctorIdStr);
        return RestHttpUtil.post()
                           .url(this.recommendRemoterConfig.getDrRecordInfoUrl())
                           .paramMap(paramMap)
                           .executeData(new ParameterizedTypeReference<ResponseVO<DoctorRecordDTO>>() {
                           });
    }

    @Override
    public PageVO<DiagnosisVO> searchDiagnosis(Long doctorId, String keyword, String skuIds, PageParamVO paramVO) throws BusinessException {

        // 搜索诊断
        Map<String, String> params = new HashMap<>();
        params.put("key", keyword == null ? "" : keyword + "");
        params.put("doctorId", doctorId == null ? null : doctorId + "");
        params.put("page", paramVO.getPage() + "");
        params.put("num", paramVO.getNum() + "");
        params.put("skuIds", skuIds == null ? "" : skuIds);

        PageVO<DiagnosisVO> pageVO = RestHttpUtil.post()
                                                 .url(this.recommendRemoterConfig.getDrDdiagnosisSearch())
                                                 .paramMap(params)
                                                 .executeData(new ParameterizedTypeReference<ResponseVO<PageVO<DiagnosisVO>>>() {
                                                 });
        List<DiagnosisVO> diagnosisVOList = pageVO.getResult();
        if (CollectionUtils.isNotEmpty(diagnosisVOList)) {
            String mainCode;
            String attachCode;
            for (DiagnosisVO diagnosisVO : diagnosisVOList) {
                mainCode = diagnosisVO.getMainCode() == null ? "" : diagnosisVO.getMainCode();
                attachCode = diagnosisVO.getAttachCode() == null ? "" : diagnosisVO.getAttachCode();
                diagnosisVO.setCode(mainCode + attachCode);
            }
        }
        return pageVO;

    }

    @Override
    public void addPrescriptionRecord(MedicalRecordBO medicalRecordBO) {

        if (medicalRecordBO == null) {
            return;
        }
        RestHttpUtil.post().url(this.recommendRemoterConfig.getEmrAddPrescriptionUrl()).body(JsonMapper.toJson(medicalRecordBO)).asyncExecuteData();
    }

    @Override
    public void sendImRecomRemind(IMRecomRemindDTO recomRemindDTO) throws BusinessException {
        RestHttpUtil.post().url(this.recommendRemoterConfig.getImRecomRemindUrl()).body(JsonMapper.toJson(recomRemindDTO)).executeData();
    }

    @Override
    public Map<Long, PatientNameVO> getPatientNames(Long doctorId, String key) throws BusinessException {

        Map<Long, PatientNameVO> patientNameMap = new HashMap<>();
        if (null == doctorId) {
            return patientNameMap;
        }

        Map<String, String> params = new HashMap<>();
        params.put("doctorId", doctorId.toString());
        params.put("namekey", key);

        return RestHttpUtil.post()
                           .url(this.recommendRemoterConfig.getPatientNamesUrl())
                           .paramMap(params)
                           .executeData(new ParameterizedTypeReference<ResponseVO<Map<Long, PatientNameVO>>>() {
                           });
    }


    @Override
    public List<MedicationBoxVO> getMedicationList(Long doctorId, Integer areaId, List<Long> pIdList, boolean isRecommend) throws BusinessException {

        if (null == pIdList || pIdList.isEmpty()) {
            return new ArrayList<>();
        }
        if (areaId == null) {
            areaId = 0;
        }
        Map<String, String> params = new HashMap<>();
        if (null != doctorId) {
            params.put("doctorId", doctorId.toString());
        } else {
            params.put("doctorId", "");
        }
        params.put("areaId", areaId.toString());
        String pIds = StringUtil.convertCollection(pIdList);
        //params.put("ids", pIds);
        //临时修改方式
        params.put("skuIds", pIds);
        params.put("isRecommend", isRecommend + "");
        String callUrl = this.recommendRemoterConfig.getGetB2cProductListUrl();
        LOGGER.info("[调用b2c获取商品列表接口]请求url:{}, parasm: {}", callUrl, params);
        List<ProductBoxBO> data = RestHttpUtil.post()
                                              .url(callUrl)
                                              .paramMap(params)
                                              .executeData(new ParameterizedTypeReference<ResponseVO<List<ProductBoxBO>>>() {
                                              });
        return data.stream()
                   .map(productBoxBO -> {
                       MedicationBoxVO medicationBoxVO = new MedicationBoxVO();
                       BeanUtils.copyProperties(productBoxBO, medicationBoxVO);
                       medicationBoxVO.setPrescribed(productBoxBO.isPrescribed());
                       medicationBoxVO.setDrugType(productBoxBO.getDrugType());
                       medicationBoxVO.setIsRecommend(productBoxBO.getRecommendFlag());
                       medicationBoxVO.setZhengda(productBoxBO.isZhengdaFlag());
                       // 是否诊所医生
                       medicationBoxVO.setModifyFlag(false);
                       // 是否已调价
                       medicationBoxVO.setModified(productBoxBO.isModified());
                       // 市场积分
                       medicationBoxVO.setMarketPoint(productBoxBO.getMarketPoint());
                       List<SkuVO> skuVOs = Lists.newArrayList();
                       productBoxBO.getSkus().forEach(productSkuBO -> {
                           SkuVO skuVO = new SkuVO();
                           BeanUtils.copyProperties(productSkuBO, skuVO);
                           skuVO.setIsDefault(productSkuBO.getDefaultFlag());
                           skuVOs.add(skuVO);
                       });

                       medicationBoxVO.setSkus(skuVOs);
                       return medicationBoxVO;
                   }).collect(Collectors.toList());
    }


    @Override
    public Map<Long, InventoryInfoVo> getMedicationInventory(List<Map<String, Object>> goodsParams, String unionId) throws BusinessException {
        Map<Long, InventoryInfoVo> retMap = new HashMap<>();
        if (goodsParams == null || goodsParams.size() == 0) {
            return retMap;
        }
        Map<String, String> params = new HashMap<>();
        params.put("unionId", unionId);
        params.put("goods", JsonMapper.toJson(goodsParams));
        String callUrl = this.recommendRemoterConfig.getGetB2cProductInventoryUrl();
        LOGGER.info("[调用B2C获取商品库存接口]请求url:{}, parasm: {}", callUrl, params);
        List<ProductInventoryBO> data = RestHttpUtil.post()
                                                    .url(callUrl)
                                                    .paramMap(params)
                                                    .executeData(new ParameterizedTypeReference<ResponseVO<List<ProductInventoryBO>>>() {
                                                    });
        List<InventoryInfoVo> collect = data.stream()
                                            .map(productInventoryBO -> {
                                                InventoryInfoVo inventoryInfoVo = new InventoryInfoVo();
                                                BeanUtils.copyProperties(productInventoryBO, inventoryInfoVo);
                                                inventoryInfoVo.setIsShort(productInventoryBO.getShorted());
                                                inventoryInfoVo.setIslimit(productInventoryBO.getLimitSale());
                                                inventoryInfoVo.setIsPresell(productInventoryBO.getPresell());
                                                return inventoryInfoVo;
                                            }).collect(Collectors.toList());

        return collect.stream().collect(Collectors.toMap(InventoryInfoVo::getSkuId, node -> node, (a, b) -> b));
    }

    @Override
    public Integer checkConsultNeedCharge(Long doctorId, Long patientId) throws BusinessException {
        Map<String, String> params = new HashMap<>();
        params.put("doctorId", doctorId.toString());
        params.put("patientId", patientId.toString());

        String callUrl = this.recommendRemoterConfig.getCheckIfNeedChargeConsult();
        LOGGER.info("[调用检查患者是否需要付费咨询接口]请求url:{}, parasm: {}", callUrl, params);
        return RestHttpUtil.post()
                           .url(callUrl)
                           .paramMap(params)
                           .executeData(new ParameterizedTypeReference<ResponseVO<Integer>>() {
                           });
    }

    @Override
    public void sendRecomPartBuyNotify(RecomBuyNotifyParamBO notifyParamBO) {
        if (notifyParamBO == null || notifyParamBO.getRecomInfoList() == null) {
            return;
        }
        String callUrl = this.recommendRemoterConfig.getBuyNotifyUrl();
        try {
            RestHttpUtil.post().url(callUrl).body(JsonMapper.toJson(notifyParamBO)).executeData();
        } catch (BusinessException e) {
            LOGGER.error("请求发送患者少购通知参数转换失败", e);
        }

    }

    @Override
    public DrRecordAuthorityBO getRecordInfoByDoctorId(Long doctorId) throws BusinessException {
        if (doctorId == null) {
            return null;
        }
        String callUrl = this.recommendRemoterConfig.getRecomRecordInfoUrl();
        return RestHttpUtil.get()
                           .url(callUrl + "?doctorId=" + doctorId)
                           .executeData(new ParameterizedTypeReference<ResponseVO<DrRecordAuthorityBO>>() {
                           });
    }

    @Override
    public List<MedicationDefaultUsageBO> getDefaultUsage(String skuIds) throws BusinessException {
        Map<String, String> params = new HashMap<String, String>();
        params.put("skuIds", skuIds);
        return RestHttpUtil.post()
                           .url(this.recommendRemoterConfig.getMedicationDefaultUsageUrl())
                           .paramMap(params)
                           .executeData(new ParameterizedTypeReference<ResponseVO<List<MedicationDefaultUsageBO>>>() {
                           });
    }

    @Override
    public boolean checkRevisitNotice(Long doctorId, Long patientId, Date startDate, Date endDate) throws BusinessException {
        Map<String, String> params = new HashMap<String, String>();
        params.put("doctorId", String.valueOf(doctorId));
        params.put("patientId", String.valueOf(patientId));
        params.put("startTime", DateUtil.formatDate(startDate, DateUtil.DATE_TIME_FORMAT));
        params.put("endTime", DateUtil.formatDate(endDate, DateUtil.DATE_TIME_FORMAT));
        return RestHttpUtil.post()
                           .url(this.recommendRemoterConfig.getRevisitNoticeUrl())
                           .body(JsonMapper.toJson(params))
                           .executeData(new ParameterizedTypeReference<ResponseVO<Boolean>>() {
                           });
    }

    @Override
    public DrRecordIdBO saveDrCase(DrCaseParams params) throws BusinessException {
        return RestHttpUtil.post()
                           .url(this.recommendRemoterConfig.getEmrSaveRecordUrl())
                           .body(JsonMapper.toJson(params))
                           .executeData(new ParameterizedTypeReference<ResponseVO<DrRecordIdBO>>() {
                           });
    }


    @Override
    public MedicalRecordDoctorBO getDrCaseByRecomId(Long recommendId) throws BusinessException {
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("recommendId", recommendId + "");
        return RestHttpUtil.post()
                           .url(this.recommendRemoterConfig.getEmrGetRecordUrl())
                           .paramMap(paramMap)
                           .executeData(new ParameterizedTypeReference<ResponseVO<MedicalRecordDoctorBO>>() {
                           });
    }

    @Override
    public void updateRecord(String recordId) throws BusinessException {
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("recordId", recordId);
        RestHttpUtil.post()
                    .url(this.recommendRemoterConfig.getEmrUpdateRecordUrl())
                    .paramMap(paramMap)
                    .executeData();
    }

    /**
     * 调用b2c获取药品列表
     * @param medicationParamBO
     * @return
     * @throws BusinessException
     */
    @Override
    public List<MedicationDetailBO> getMedicationDetailList(MedicationParamBO medicationParamBO) throws BusinessException {
        return RestHttpUtil.post()
                           .url(this.recommendRemoterConfig.getGetB2cProductListDetailUrl())
                           .body(JsonMapper.toJson(medicationParamBO))
                           .executeData(new ParameterizedTypeReference<ResponseVO<List<MedicationDetailBO>>>() {
                           });
    }

    @Override
    public Integer getDrConsultChargeStatus(Long doctorId, Long patientId) throws BusinessException {
        Map<String, String> param = new HashMap<>();
        param.put("doctorId", doctorId + "");
        param.put("patientId", patientId + "");
        return RestHttpUtil.post()
                           .url(this.recommendRemoterConfig.getDrConsultChargeStatusUrl())
                           .paramMap(param)
                           .executeData(new ParameterizedTypeReference<ResponseVO<Integer>>() {
                           });
    }

}
